package com.nh.alarm;

import com.haikang.HCNetSDK;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import sun.misc.Signal;
import sun.misc.SignalHandler;

import java.text.DateFormat;
import java.util.logging.Logger;


public class Starter {
    private static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;
    private static String DEVICE_IP = "192.168.2.253";
    private static short DEVICE_PORT = 8000;
    private static String USER_NAME = "admin";
    private static String USER_PASSWD = "litao888";
    public static String UPLOAD_URL = "http://www.jsxrk.xin/public/api/nursery/education/checkon";
    private static final Logger LOGGER = Logger.getLogger("Starter");


    private static AcsAlarmThread acsAlarmThread = AcsAlarmThread.getInstance();

    public static void main(String[] args) {
//        if(args.length != 5) {
//            System.out.println("参数不正确");
//            System.exit(1);
//        }
//
//        DEVICE_IP = args[0];
//        DEVICE_PORT = (short) Integer.parseInt(args[1]);
//        USER_NAME = args[2];
//        USER_PASSWD = args[3];
//        UPLOAD_URL = args[4];

        LOGGER.info("DEVICE_IP:" + DEVICE_IP);
        LOGGER.info("DEVICE_PORT:" + DEVICE_PORT);
        LOGGER.info("USER_NAME:" + USER_NAME);
        LOGGER.info("UPLOAD_URL:" + UPLOAD_URL);

        hCNetSDK.NET_DVR_Init();
        hCNetSDK.NET_DVR_SetLogToFile(true, null, false);
        hCNetSDK.NET_DVR_SetConnectTime(2000, 1);
        hCNetSDK.NET_DVR_SetReconnect(10000, true);

        HCNetSDK.NET_DVR_DEVICEINFO_V30 deviceInfo = getDeviceInfo();

        NativeLong nlUserID = hCNetSDK.NET_DVR_Login_V30(DEVICE_IP, DEVICE_PORT, USER_NAME, USER_PASSWD, deviceInfo);
        if (nlUserID.intValue() == -1) {
            LOGGER.warning("user login failed");
            hCNetSDK.NET_DVR_Cleanup();
            return;
        }

        LOGGER.info("set callback");
        Pointer pUser = null;
        hCNetSDK.NET_DVR_SetDVRMessageCallBack_V30(new FMSGCallBack(), pUser);

        LOGGER.info("SetupAlarmChan");
        NativeLong lHandle = hCNetSDK.NET_DVR_SetupAlarmChan_V30(nlUserID);
        if (lHandle.intValue() < 0) {
            hCNetSDK.NET_DVR_Logout(nlUserID);
            hCNetSDK.NET_DVR_Cleanup();
            return;
        }

        KillHandler killHandler = new KillHandler();
        Signal.handle(new Signal("TERM"), killHandler);

        try {
            acsAlarmThread.start();
            acsAlarmThread.join();
        } catch (Exception e) {
            e.printStackTrace();
        }

        LOGGER.info("CloseAlarmChan");
        if (!hCNetSDK.NET_DVR_CloseAlarmChan_V30(lHandle)) {
            hCNetSDK.NET_DVR_Logout(nlUserID);
            hCNetSDK.NET_DVR_Cleanup();
            return;
        }

        LOGGER.info("Logout");
        hCNetSDK.NET_DVR_Logout(nlUserID);
        hCNetSDK.NET_DVR_Cleanup();
        System.exit(0);
    }

    private static HCNetSDK.NET_DVR_DEVICEINFO_V30 getDeviceInfo() {
        return new HCNetSDK.NET_DVR_DEVICEINFO_V30();
    }

    public static class FMSGCallBack implements HCNetSDK.FMSGCallBack {
        public void invoke(NativeLong lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, HCNetSDK.RECV_ALARM pAlarmInfo,
                           int dwBufLen, Pointer pUser) {
            System.out.println(String.format("0x%x", lCommand.intValue()));
            if (lCommand.intValue() == HCNetSDK.COMM_ALARM_ACS) {
                HCNetSDK.NET_DVR_ACS_ALARM_INFO alarm = new HCNetSDK.NET_DVR_ACS_ALARM_INFO();
                alarm.write();
                Pointer pointer = alarm.getPointer();
                pointer.write(0, pAlarmInfo.RecvBuffer, 0, alarm.size());
                alarm.read();

                System.out.println(String.format("dwMajor=0x%x, dwMinor=0x%x", alarm.dwMajor, alarm.dwMinor));
                if (alarm.dwMajor == 0x5) {
                    String datetime = alarm.struTime.toStringTime();
                    String cardNo = new String(alarm.struAcsEventInfo.byCardNo);
                    cardNo = cardNo.trim();
                    System.out.println(String.format("cardNo = %s", cardNo));
                    alarm.clear();
                    if (!cardNo.isEmpty()) {
                        ACSEventAlarm msg = new ACSEventAlarm(cardNo.trim(), datetime.trim());
                        acsAlarmThread.addMessage(msg);
                    }
                }
                alarm.clear();
            }
        }
    }

    public static class KillHandler implements SignalHandler {
        @Override
        public void handle(Signal signal) {
            acsAlarmThread.setStopped(true);
            LOGGER.info("KillHandler:" + signal.getNumber());
            LOGGER.info("KillHandler:" + signal.getName());
        }
    }
}
